﻿using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using RBAC.Api.Infaction;
using RBAC.Api.Read.Common;
using System.Reflection;
using System.Text;

namespace RBAC.Api.Read.Extensions
{
    /// <summary>
    /// 扩展方法 静态类 静态方法 this 关键字
    /// </summary>
    public static class ServiceCollectionExtensions
    {
        public static WebApplicationBuilder Inject(this WebApplicationBuilder builder)
        {
            // Add services to the container.

            builder.Services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();

            //注册上下文
            builder.Services.AddDbContextAccessor<MyDbContext>(builder.Configuration.GetConnectionString("Conn"),builder.Environment.IsProduction());

            //注册仓储接口
            builder.Services.AddScoped(typeof(IBaseRepositry<>), typeof(BaseRepositry<>));

            //注册中介者
            builder.Services.AddMediatR(x =>
            {
                x.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());
            });

            //注册Token服务
            builder.Services.AddTransient<TokenServices>();

            //注册自动映射
            builder.Services.AddAutoMapper(typeof(AutoMapperFile));

            builder.Services.AddScoped<IIdentifyService, IdentifyService>();

            builder.Services.AddHttpContextAccessor();

            // 配置Swagger
            builder.Services.AddSwaggerGen(o =>
            {
                string aa = AppDomain.CurrentDomain.BaseDirectory + "RBAC.Api.Read.xml";
                o.IncludeXmlComments(aa, true);

                // 显示 授权信息
                o.AddSecurityDefinition("Bearer", new Microsoft.OpenApi.Models.OpenApiSecurityScheme()
                {
                    Description = "添加JWT授权Token：Bearer Token值",
                    Name = "Authorization",
                    In = Microsoft.OpenApi.Models.ParameterLocation.Header,
                    Type = Microsoft.OpenApi.Models.SecuritySchemeType.ApiKey,
                    BearerFormat = "JWT",
                    Scheme = "Bearer"
                });
                o.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id = "Bearer"
                            }
                        },
                        new string[]
                        {

                        }
                    }
                });
            });


            // JWT Authentication 配置
            var jwtSettings = builder.Configuration.GetSection("JwtSettings");
            var secretKey = Encoding.UTF8.GetBytes(jwtSettings["SecretKey"]);

            builder.Services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.RequireHttpsMetadata = false;
                options.SaveToken = true;
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(secretKey),
                    ValidateIssuer = true,
                    ValidIssuer = jwtSettings["Issuer"],
                    ValidateAudience = true,
                    ValidAudience = jwtSettings["Audience"],
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.Zero // 默认是5分钟，这里设置为0
                };
            });
            builder.Services.AddAuthorization();



            return builder;
               
        }
        /// <summary>
        /// 注册上下文
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="services"></param>
        /// <param name="connectionString">连接字符串</param>
        /// <param name="enableSqlLog">是否启用sql日志</param>
        /// <returns></returns>
        public static IServiceCollection AddDbContextAccessor<T>(this IServiceCollection services, string connectionString,
            bool enableSqlLog) where T : DbContext
        {
            return services.AddDbContext<MyDbContext>(x =>
            {
                //配置MyDbContext的重试策略
                x.UseMySql(connectionString,new MySqlServerVersion("5.7"),
                        action =>
                        {
                            action.EnableRetryOnFailure(
                                maxRetryCount: 10,//最大重试次数
                                maxRetryDelay: TimeSpan.FromSeconds(60),//每次重试间隔时间,最大延迟
                                errorNumbersToAdd: null);//
                        }).EnableSensitiveDataLogging();//启用敏感数据日志记录,便于调试,但在生产环境中应谨慎使用以避免泄露敏感信息

                if (enableSqlLog)
                {
                    //配置日志记录
                    x.UseLoggerFactory(LoggerFactory.Create(builder => builder.AddFilter(
                        category: DbLoggerCategory.Database.Name, //类别
                        level: LogLevel.Information//日志级别
                        ).AddConsole())); //控制台日志
                }

            });
        }
    }
}
